// Learn TypeScript:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;
import {MaxRectsBinPack} from './maxrects/MaxRectsBinPack'

cc.dynamicAtlasManager.enabled = false;
@ccclass
export default class XYAtlas extends cc.Component {
    static get ins(): XYAtlas {
        return this._ins;
    }

    static set ins(value: XYAtlas) {
        this._ins = value;
    }

    private static _ins: XYAtlas;

    @property([cc.SpriteFrame])
    spriteFrames: cc.SpriteFrame[] = [];

    @property(cc.Sprite)
    debugSprite: cc.Sprite = null;

    @property
    width = 1024;
    @property
    height = 1024;

    _texture: cc.RenderTexture;
    _textures: { [index: string]: cc.Texture2D } = {};

    // LIFE-CYCLE CALLBACKS:
    _pack: MaxRectsBinPack;

    _loc: cc.Vec2;

    onLoad() {
        XYAtlas._ins = this;
        cc.dynamicAtlasManager.enabled = false;
        this.initTexture();
        this.spriteFrames.forEach(sf => {
            if (sf)
                this.insertSpriteFrame(sf);
        })
    }

    initTexture() {
        this._pack = new MaxRectsBinPack(this.width, this.height, false);
        this._texture = new cc.RenderTexture();
        this._texture.initWithSize(this.width, this.height);
        this._loc = new cc.Vec2(0, 0);
        cc.log(this._texture, this._pack);
        if (this.debugSprite)
            this.debugSprite.spriteFrame = new cc.SpriteFrame(this._texture);
    }

    insertSpriteFrame(sf: cc.SpriteFrame) {
        let tx = sf.getTexture();

        //引入的maxRect算法不支持space 所以带入width height计算
        let rst = this._pack.insert(tx.width, tx.height)

        if (rst.height == 0) {
            cc.warn('xyatlas: texture full');
            return null;
        }

        cc.log(sf, tx);
        //@ts-ignore
        this._textures[sf._uuid] = new cc.Rect(rst.x, rst.y, tx.width, tx.height);;
        //@ts-ignore
        this._texture.drawTextureAt(tx, rst.x, rst.y);
    }

    getTexture(uuid) {
        if (this._textures[uuid])
            return {
                texture: this._texture,
                frame: this._textures[uuid]
            };
    }

    start() {

    }

    protected onDestroy() {
        this._texture.destroy();
        this._pack.clear();
        this._textures = {};

    }

    // update (dt) {}
}
